//! library_demo
//!
//! 一个演示库 crate，展示了如何创建可复用的 Rust 库
//!
//! ## 知识点总结
//!
//! | 模块 | 功能 | 用途 |
//! |------|------|-----|
//! | math | 数学运算 | 基本数学函数 |
//! | utils | 工具函数 | 通用工具方法 |

/// 数学运算模块
pub mod math {
    /// 两数相加
    ///
    /// # Examples
    ///
    /// ```
    /// use library_demo::math::add;
    ///
    /// assert_eq!(add(2, 3), 5);
    /// ```
    pub fn add(left: usize, right: usize) -> usize {
        left + right
    }

    /// 两数相减
    ///
    /// # Examples
    ///
    /// ```
    /// use library_demo::math::subtract;
    ///
    /// assert_eq!(subtract(5, 3), 2);
    /// ```
    pub fn subtract(left: usize, right: usize) -> usize {
        left - right
    }

    /// 两数相乘
    ///
    /// # Examples
    ///
    /// ```
    /// use library_demo::math::multiply;
    ///
    /// assert_eq!(multiply(3, 4), 12);
    /// ```
    pub fn multiply(left: usize, right: usize) -> usize {
        left * right
    }

    /// 两数相除
    ///
    /// # Examples
    ///
    /// ```
    /// use library_demo::math::divide;
    ///
    /// assert_eq!(divide(10, 2), 5);
    /// ```
    ///
    /// # Panics
    ///
    /// 当除数为0时会panic
    ///
    /// ```should_panic
    /// use library_demo::math::divide;
    ///
    /// divide(10, 0);
    /// ```
    pub fn divide(dividend: usize, divisor: usize) -> usize {
        if divisor == 0 {
            panic!("Division by zero");
        }
        dividend / divisor
    }
}

/// 工具函数模块
pub mod utils {
    /// 检查一个数是否为偶数
    ///
    /// # Examples
    ///
    /// ```
    /// use library_demo::utils::is_even;
    ///
    /// assert_eq!(is_even(4), true);
    /// assert_eq!(is_even(5), false);
    /// ```
    pub fn is_even(n: usize) -> bool {
        n % 2 == 0
    }

    /// 检查一个数是否为奇数
    ///
    /// # Examples
    ///
    /// ```
    /// use library_demo::utils::is_odd;
    ///
    /// assert_eq!(is_odd(5), true);
    /// assert_eq!(is_odd(4), false);
    /// ```
    pub fn is_odd(n: usize) -> bool {
        n % 2 != 0
    }

    /// 计算向量的平均值
    ///
    /// # Examples
    ///
    /// ```
    /// use library_demo::utils::average;
    ///
    /// let numbers = vec![1, 2, 3, 4, 5];
    /// assert_eq!(average(&numbers), 3.0);
    /// ```
    ///
    /// # Panics
    ///
    /// 当向量为空时会panic
    ///
    /// ```should_panic
    /// use library_demo::utils::average;
    ///
    /// let numbers = vec![];
    /// average(&numbers);
    /// ```
    pub fn average(numbers: &[usize]) -> f64 {
        if numbers.is_empty() {
            panic!("Cannot calculate average of empty vector");
        }
        numbers.iter().sum::<usize>() as f64 / numbers.len() as f64
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_add() {
        assert_eq!(math::add(2, 2), 4);
    }

    #[test]
    fn test_subtract() {
        assert_eq!(math::subtract(5, 3), 2);
    }

    #[test]
    fn test_multiply() {
        assert_eq!(math::multiply(3, 4), 12);
    }

    #[test]
    fn test_divide() {
        assert_eq!(math::divide(10, 2), 5);
    }

    #[test]
    #[should_panic(expected = "Division by zero")]
    fn test_divide_by_zero() {
        math::divide(10, 0);
    }

    #[test]
    fn test_is_even() {
        assert_eq!(utils::is_even(4), true);
        assert_eq!(utils::is_even(5), false);
    }

    #[test]
    fn test_is_odd() {
        assert_eq!(utils::is_odd(5), true);
        assert_eq!(utils::is_odd(4), false);
    }

    #[test]
    fn test_average() {
        let numbers = vec![1, 2, 3, 4, 5];
        assert_eq!(utils::average(&numbers), 3.0);
    }

    #[test]
    #[should_panic(expected = "Cannot calculate average of empty vector")]
    fn test_average_empty() {
        let numbers = vec![];
        utils::average(&numbers);
    }
}
